home *** CD-ROM | disk | FTP | other *** search
/ Micromanía 92 / CDMM92_1.ISO / SOF 2 SDK / sof2sdk-101.msi / _92D6AC311BB48EBA344BBABC89DA6AB0 / _73F51B4492564D8A86FAF080C80DF12B < prev    next >
Encoding:
Text File  |  2002-07-01  |  10.6 KB  |  337 lines

  1. // Copyright (C) 2000-2001 Raven Software, Inc.
  2. //
  3. // g_antilag.c -- handles server side anti-lag 
  4.  
  5. #include "g_local.h"
  6.  
  7.  
  8. /*
  9. ================
  10. G_UpdateClientAntiLag
  11. ================
  12. */
  13. void G_UpdateClientAntiLag ( gentity_t* ent )
  14. {
  15.     int            head;
  16.     int            newtime;
  17.  
  18.     head = ent->client->antilagHead;
  19.  
  20.     // If on a new frame snap the head up to the end of the last frame and 
  21.     // add a new head
  22.     if ( ent->client->antilag[head].leveltime < level.time )
  23.     {
  24.         ent->client->antilag[head].time = level.previousTime;
  25.  
  26.         // Move to the next position 
  27.         if ( (++ent->client->antilagHead) > MAX_ANTILAG )
  28.         {
  29.             ent->client->antilagHead = 0;
  30.         }
  31.  
  32.         head = ent->client->antilagHead;
  33.     }
  34.  
  35.     // Bots only move once per frame
  36.     if ( ent->r.svFlags & SVF_BOT ) 
  37.     {
  38.         newtime = level.time;
  39.     } 
  40.     else 
  41.     {
  42.         // calculate the actual server time        
  43.         newtime = level.previousTime + trap_Milliseconds() - level.frameStartTime;
  44.         
  45.         if ( newtime > level.time ) 
  46.         {
  47.             newtime = level.time;
  48.         } 
  49.         else if ( newtime <= level.previousTime ) 
  50.         {
  51.             newtime = level.previousTime + 1;
  52.         }
  53.     }
  54.  
  55.     // Copy the clients current state into the antilag cache
  56.     ent->client->antilag[head].leveltime = level.time;
  57.     ent->client->antilag[head].time = newtime;
  58.     VectorCopy ( ent->r.currentOrigin, ent->client->antilag[head].rOrigin );
  59.     VectorCopy ( ent->r.currentAngles, ent->client->antilag[head].rAngles );
  60.     VectorCopy ( ent->r.mins, ent->client->antilag[head].mins );
  61.     VectorCopy ( ent->r.maxs, ent->client->antilag[head].maxs );
  62.  
  63.     VectorCopy ( ent->client->ghoulLegsAngles, ent->client->antilag[head].legsAngles );
  64.     VectorCopy ( ent->client->ghoulLowerTorsoAngles, ent->client->antilag[head].lowerTorsoAngles );
  65.     VectorCopy ( ent->client->ghoulUpperTorsoAngles, ent->client->antilag[head].upperTorsoAngles );
  66.     VectorCopy ( ent->client->ghoulHeadAngles, ent->client->antilag[head].headAngles );
  67.  
  68.     ent->client->antilag[head].legsAnim  = ent->s.legsAnim;
  69.     ent->client->antilag[head].torsoAnim = ent->s.torsoAnim;
  70.     ent->client->antilag[head].pm_flags  = ent->client->ps.pm_flags;
  71.     ent->client->antilag[head].leanTime  = ent->client->ps.leanTime;
  72. }
  73.  
  74. /*
  75. ================
  76. G_UndoClientAntiLag
  77. ================
  78. */
  79. void G_UndoClientAntiLag ( gentity_t* ent )
  80. {
  81.     // If the client isnt already in the past then 
  82.     // dont bother doing anything
  83.     if ( ent->client->antilagUndo.leveltime != level.time  )
  84.         return;
  85.  
  86.     // Move the client back into reality by moving over the undo information
  87.     VectorCopy ( ent->client->antilagUndo.rOrigin, ent->r.currentOrigin );
  88.     VectorCopy ( ent->client->antilagUndo.rAngles, ent->r.currentAngles );
  89.     VectorCopy ( ent->client->antilagUndo.mins, ent->r.mins );
  90.     VectorCopy ( ent->client->antilagUndo.maxs, ent->r.maxs );
  91.  
  92.     VectorCopy ( ent->client->antilagUndo.legsAngles, ent->client->ghoulLegsAngles );
  93.     VectorCopy ( ent->client->antilagUndo.lowerTorsoAngles, ent->client->ghoulLowerTorsoAngles );
  94.     VectorCopy ( ent->client->antilagUndo.upperTorsoAngles, ent->client->ghoulUpperTorsoAngles );
  95.     VectorCopy ( ent->client->antilagUndo.headAngles, ent->client->ghoulHeadAngles );
  96.  
  97.     ent->s.legsAnim = ent->client->antilagUndo.legsAnim;
  98.     ent->s.torsoAnim = ent->client->antilagUndo.torsoAnim;
  99.     ent->client->ps.pm_flags = ent->client->antilagUndo.pm_flags;
  100.     ent->client->ps.leanTime = ent->client->antilagUndo.leanTime;
  101.  
  102.     // Mark the undo information so it cant be used again
  103.     ent->client->antilagUndo.leveltime = 0;
  104. }
  105.  
  106. /*
  107. ================
  108. G_ApplyClientAntiLag
  109. ================
  110. */
  111. void G_ApplyClientAntiLag ( gentity_t* ent, int time )
  112. {
  113.     float    lerp;
  114.     int        from;
  115.     int        to;
  116.  
  117.     // Find the two pieces of history information that sandwitch the
  118.     // time we are looking for
  119.     from = ent->client->antilagHead;
  120.     to   = ent->client->antilagHead;
  121.     do
  122.     {
  123.         if ( ent->client->antilag[from].time <= time )
  124.         {
  125.             break;
  126.         }
  127.  
  128.         to = from;
  129.         from--;
  130.  
  131.         if ( from < 0 )
  132.         {
  133.             from = MAX_ANTILAG - 1;
  134.         }
  135.     }
  136.     while ( from != ent->client->antilagHead );
  137.  
  138.     // If the from is equal to the to then there wasnt even
  139.     // one piece of information worth using so just use the current time frame
  140.     if ( from == to )
  141.     {
  142.         return;
  143.     }
  144.  
  145.     // Save the undo information if its not already saved
  146.     if ( ent->client->antilagUndo.leveltime != level.time )
  147.     {
  148.         // Save the undo information
  149.         ent->client->antilagUndo.leveltime = level.time;
  150.  
  151.         VectorCopy ( ent->r.currentOrigin, ent->client->antilagUndo.rOrigin );
  152.         VectorCopy ( ent->r.currentAngles, ent->client->antilagUndo.rAngles );
  153.         VectorCopy ( ent->r.mins, ent->client->antilagUndo.mins );
  154.         VectorCopy ( ent->r.maxs, ent->client->antilagUndo.maxs );
  155.  
  156.         VectorCopy ( ent->client->ghoulLegsAngles, ent->client->antilagUndo.legsAngles );
  157.         VectorCopy ( ent->client->ghoulLowerTorsoAngles, ent->client->antilagUndo.lowerTorsoAngles );
  158.         VectorCopy ( ent->client->ghoulUpperTorsoAngles, ent->client->antilagUndo.upperTorsoAngles );
  159.         VectorCopy ( ent->client->ghoulHeadAngles, ent->client->antilagUndo.headAngles );
  160.  
  161.         ent->client->antilagUndo.legsAnim  = ent->s.legsAnim;
  162.         ent->client->antilagUndo.torsoAnim = ent->s.torsoAnim;
  163.         ent->client->antilagUndo.pm_flags  = ent->client->ps.pm_flags;
  164.         ent->client->antilagUndo.leanTime  = ent->client->ps.leanTime;
  165.     }
  166.  
  167.     // If the best history found was the last in the list then
  168.     // dont lerp, just use the last one
  169.     if ( from == ent->client->antilagHead )
  170.     {
  171.         VectorCopy ( ent->client->antilag[to].rOrigin, ent->r.currentOrigin );
  172.         VectorCopy ( ent->client->antilag[to].rAngles, ent->r.currentAngles );
  173.         VectorCopy ( ent->client->antilag[to].mins, ent->r.maxs );
  174.         VectorCopy ( ent->client->antilag[to].maxs, ent->r.mins );
  175.  
  176.         VectorCopy ( ent->client->antilag[to].legsAngles, ent->client->ghoulLegsAngles );
  177.         VectorCopy ( ent->client->antilag[to].lowerTorsoAngles, ent->client->ghoulLowerTorsoAngles );
  178.         VectorCopy ( ent->client->antilag[to].upperTorsoAngles, ent->client->ghoulUpperTorsoAngles );
  179.         VectorCopy ( ent->client->antilag[to].headAngles, ent->client->ghoulHeadAngles );
  180.  
  181.         ent->s.legsAnim  = ent->client->antilag[to].legsAnim;
  182.         ent->s.torsoAnim = ent->client->antilag[to].torsoAnim;
  183.         ent->client->ps.pm_flags = ent->client->antilag[to].pm_flags;
  184.         ent->client->ps.leanTime = ent->client->antilag[to].leanTime;
  185.     }
  186.     else
  187.     {
  188.         // Calculate the lerp value to use for the vectors
  189.         lerp = (float)(time - ent->client->antilag[from].time) / (float)(ent->client->antilag[to].time - ent->client->antilag[from].time);
  190.  
  191.         // Lerp all the vectors between the before and after history information
  192.         LerpVector ( ent->client->antilag[from].rOrigin, ent->client->antilag[to].rOrigin, lerp, ent->r.currentOrigin );
  193.         LerpVector ( ent->client->antilag[from].rAngles, ent->client->antilag[to].rAngles, lerp, ent->r.currentAngles );
  194.         LerpVector ( ent->client->antilag[from].maxs, ent->client->antilag[to].maxs, lerp, ent->r.maxs );
  195.         LerpVector ( ent->client->antilag[from].mins, ent->client->antilag[to].mins, lerp, ent->r.mins );
  196.  
  197.         LerpVector ( ent->client->antilag[from].legsAngles, ent->client->antilag[to].legsAngles, lerp, ent->client->ghoulLegsAngles );
  198.         LerpVector ( ent->client->antilag[from].lowerTorsoAngles, ent->client->antilag[to].lowerTorsoAngles, lerp, ent->client->ghoulLowerTorsoAngles );
  199.         LerpVector ( ent->client->antilag[from].upperTorsoAngles, ent->client->antilag[to].upperTorsoAngles, lerp, ent->client->ghoulUpperTorsoAngles );
  200.         LerpVector ( ent->client->antilag[from].headAngles, ent->client->antilag[to].headAngles, lerp, ent->client->ghoulHeadAngles );
  201.  
  202.         ent->client->ps.leanTime = ent->client->antilag[from].leanTime + (ent->client->antilag[from].leanTime-ent->client->antilag[to].leanTime) * lerp;
  203.  
  204.         ent->s.legsAnim  = ent->client->antilag[to].legsAnim;
  205.         ent->s.torsoAnim = ent->client->antilag[to].torsoAnim;
  206.         ent->client->ps.pm_flags = ent->client->antilag[to].pm_flags;
  207.     }
  208. }
  209.  
  210. /*
  211. ================
  212. G_UndoAntiLag
  213. ================
  214. */
  215. void G_UndoAntiLag ( void )
  216. {
  217.     int i;
  218.  
  219.     // Undo all history
  220.     for ( i = 0; i < level.numConnectedClients; i ++ )
  221.     {
  222.         gentity_t* other = &g_entities[level.sortedClients[i]];
  223.         
  224.         if ( other->client->pers.connected != CON_CONNECTED )
  225.         {
  226.             continue;
  227.         }
  228.  
  229.         // Skip clients that are spectating
  230.         if ( G_IsClientSpectating ( other->client ) || G_IsClientDead ( other->client ) )
  231.         {
  232.             continue;
  233.         }
  234.  
  235.         if ( other->r.svFlags & SVF_DOUBLED_BBOX )
  236.         {
  237.             // Put the hitbox back the way it was
  238.             other->r.maxs[0] = other->client->maxSave[0];
  239.             other->r.maxs[1] = other->client->maxSave[1];
  240.             other->r.mins[0] = other->client->minSave[0];
  241.             other->r.mins[1] = other->client->minSave[1];
  242.  
  243.             other->r.svFlags &= (~SVF_DOUBLED_BBOX);
  244.         }
  245.  
  246.         G_UndoClientAntiLag ( other );
  247.  
  248.         // Relink the entity into the world
  249.         trap_LinkEntity ( other );
  250.     }
  251. }
  252.  
  253. /*
  254. ================
  255. G_ApplyAntiLag
  256. ================
  257. */
  258. void G_ApplyAntiLag ( gentity_t* ref, qboolean enlargeHitBox )
  259. {
  260.     int i;
  261.     int reftime;
  262.  
  263.     // Figure out the reference time based on the reference clients server time
  264.     reftime = ref->client->pers.cmd.serverTime;
  265.     if ( reftime > level.time ) 
  266.     {
  267.         reftime = level.time;
  268.     }
  269.  
  270.     // Move all the clients back into the reference clients time frame.
  271.     for ( i = 0; i < level.numConnectedClients; i ++ )
  272.     {
  273.         gentity_t* other = &g_entities[level.sortedClients[i]];
  274.  
  275.         if ( other->client->pers.connected != CON_CONNECTED )
  276.         {
  277.             continue;
  278.         }
  279.  
  280.         // Skip the reference client
  281.         if ( other == ref )
  282.         {
  283.             continue;
  284.         }
  285.  
  286.         // Skip entities not in use
  287.         if ( !other->inuse )
  288.         {
  289.             continue;
  290.         }
  291.  
  292.         // Skip clients that are spectating
  293.         if ( G_IsClientSpectating ( other->client ) || G_IsClientDead ( other->client ) )
  294.         {
  295.             continue;
  296.         }
  297.  
  298.         // Dont bring them back in time unless requested
  299.         if ( !(ref->r.svFlags & SVF_BOT) & ref->client->pers.antiLag )
  300.         {
  301.             // Apply the antilag to this player
  302.             G_ApplyClientAntiLag ( other, reftime );
  303.         }
  304.  
  305.         if ( enlargeHitBox )
  306.         {
  307.             other->client->minSave[0] = other->r.mins[0];
  308.             other->client->minSave[1] = other->r.mins[1];
  309.             other->client->maxSave[0] = other->r.maxs[0];
  310.             other->client->maxSave[1] = other->r.maxs[1];
  311.  
  312.             // Adjust the hit box to account for hands and such 
  313.             // that are sticking out of the normal bounding box
  314.  
  315.             if ( other->client->ps.pm_flags & PMF_LEANING )
  316.             {
  317.                 other->r.maxs[0] *= 3.0f;
  318.                 other->r.maxs[1] *= 3.0f;
  319.                 other->r.mins[0] *= 3.0f;
  320.                 other->r.mins[1] *= 3.0f;
  321.             }
  322.             else
  323.             {
  324.                 other->r.maxs[0] *= 2.0f;
  325.                 other->r.maxs[1] *= 2.0f;
  326.                 other->r.mins[0] *= 2.0f;
  327.                 other->r.mins[1] *= 2.0f;
  328.             }
  329.  
  330.             other->r.svFlags |= SVF_DOUBLED_BBOX;
  331.         }
  332.  
  333.         // Relink the entity into the world
  334.         trap_LinkEntity ( other );
  335.     }    
  336. }
  337.